package com.project.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.base.entity.bo.SciencePersonBo;
import com.base.entity.vo.SciencePersonVo;
import com.base.service.SciencePersonService;
import com.common.core.domain.entity.SysUser;
import com.common.utils.SecurityUtils;
import com.common.utils.StringUtils;
import com.common.utils.bean.BeanUtils;
import com.project.domain.bo.VProjectMemberBo;
import com.project.domain.entity.BizProjectMemberAlteration;
import com.project.domain.entity.BizYfContract;
import com.project.domain.entity.BizYfContractMember;
import com.project.domain.entity.VProject;
import com.project.domain.entity.xjProject.BizXjProject;
import com.project.domain.entity.xjProject.BizXjProjectMember;
import com.project.domain.entity.zxProject.BizZxProject;
import com.project.domain.entity.zxProject.BizZxProjectMember;
import com.project.mapper.ProjectInitMapper;
import com.project.mapper.ProjectMembersMapper;
import com.project.mapper.YfContractMapper;
import com.project.mapper.YfContractMemberMapper;
import com.project.mapper.xjProject.XjProjectMapper;
import com.project.mapper.xjProject.XjProjectMemberMapper;
import com.project.mapper.zxProject.ZxProjectMapper;
import com.project.mapper.zxProject.ZxProjectMemberMapper;
import com.project.service.IMemberService;
import com.project.service.IYfContractMemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Transactional
public class ProjectMemberServiceImpl implements IMemberService {
    @Autowired
    ProjectMembersMapper projectMemberMapper;

    @Autowired
    XjProjectMemberMapper xjProjectMemberMapper ;

    @Autowired
    ZxProjectMemberMapper zxProjectMemberMapper;

    @Autowired
    ProjectInitMapper projectInitMapper;

    @Autowired
    ZxProjectMapper zxProjectMapper;

    @Autowired
    XjProjectMapper xjProjectMapper;

    @Autowired
    SciencePersonService sciencePersonService;

    @Autowired
    ProjectInitServiceImpl projectInitService;

    @Autowired
    YfContractMemberServiceImpl yfMemberService;

    @Autowired
    private YfContractMemberMapper yfContractMemberMapper;

    @Autowired
    private YfContractMapper yfContractMapper;

    /**
     * 获取成员列表（校级、纵向）
     * @param projectMemberBo
     * @return
     */
    public List<BizZxProjectMember> getMemList(VProjectMemberBo projectMemberBo){
        return projectMemberMapper.getMemberList(projectMemberBo);
    }

    /**
     * 保存校级项目成员信息
     * @param xjProjectMemberList
     * @return
     */
    public String saveXjMemberInfos(List<BizXjProjectMember> xjProjectMemberList){
        String res = "保存成功！";
        try{
            if(xjProjectMemberList != null && xjProjectMemberList.size() > 0){
                String proId = xjProjectMemberList.get(0).getProjectId();
                if(StringUtils.isNotBlank(proId)){
                    String[] ids = null;
                    res = delMemberInfo(ids, proId,"xj");
                }

                List<String> authorPids = new ArrayList<>();
                List<String> authorUnits = new ArrayList<>();
                for(int m = 0; m < xjProjectMemberList.size();m++){
                    BizXjProjectMember bizXjProjectMember = xjProjectMemberList.get(m);
                    bizXjProjectMember.setOrderId((long)(m+1));
                    bizXjProjectMember.setJoinStateId("1");
                    bizXjProjectMember.setWorkRatio(new BigDecimal(0));
                    xjProjectMemberMapper.insert(bizXjProjectMember);

                    //反写主表
                    authorPids.add(bizXjProjectMember.getPersonId());
                    authorUnits.add(bizXjProjectMember.getUnitId());
                    BizXjProject bizXjProject = new BizXjProject();
                    bizXjProject.setAuthorpids(authorPids.stream().collect(Collectors.joining(",")));
                    bizXjProject.setAuthorunitids(authorUnits.stream().collect(Collectors.joining(",")));
                    bizXjProject.setId(proId);

                    //编辑时间编辑人
                    SysUser loginUser = SecurityUtils.getLoginUser().getUser();
                    Date date = new Date();
                    SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    bizXjProject.setLasteditdate(dateFormat.parse(dateFormat.format(date)));
                    bizXjProject.setLasteditusername(loginUser.getNickName());
                    bizXjProject.setLastedituserid(loginUser.getUserRealId());
                    xjProjectMapper.updateById(bizXjProject);
                }
            }
        }catch (Exception exception){
            res = "保存项目成员信息失败！";
        }

        return res;
    }

    /**
     * 保存纵向项目成员信息
     * @param memberZxList
     * @return
     */
    public String saveZxMemberInfos(List<BizZxProjectMember> memberZxList){
        String res = "保存成功！";
        try{
            if(memberZxList != null && memberZxList.size() > 0){
                String proId = memberZxList.get(0).getProjectId();
                if(StringUtils.isNotBlank(proId)){
                    //更新项目：人员先全删了，然后再把所有新建
                    String[] ids = null;
                    delMemberInfo(ids, proId,"zx");
                }

                List<String> authorPids = new ArrayList<>();
                List<String> authorUnits = new ArrayList<>();
                for(int m = 0; m < memberZxList.size();m++){
                    BizZxProjectMember bizZxProjectMember = memberZxList.get(m);
                    bizZxProjectMember.setOrderId((long)(m+1));
                    zxProjectMemberMapper.insert(bizZxProjectMember);

                    //反写主表
                    authorPids.add(bizZxProjectMember.getPersonId());
                    authorUnits.add(bizZxProjectMember.getUnitId());
                    BizZxProject bizZxProject = new BizZxProject();
                    bizZxProject.setAuthorpids(authorPids.stream().collect(Collectors.joining(",")));
                    bizZxProject.setAuthorunitids(authorUnits.stream().collect(Collectors.joining(",")));
                    bizZxProject.setId(proId);
                    zxProjectMapper.updateById(bizZxProject);
                }
            }
        }catch (Exception exception){
            res = "保存项目成员信息失败！";
        }

        return res;
    }

    /**
     * 保存横向项目成员信息
     * @param memberYfList
     * @return
     */
    public String saveYFMemberInfos(List<BizYfContractMember> memberYfList){
        String res = "保存成功！";
        try{
            if(memberYfList != null && memberYfList.size() > 0){
                String proId = memberYfList.get(0).getContractId();
                if(StringUtils.isNotBlank(proId)){
                    //更新项目：人员先全删了，然后再把所有新建
                    String[] ids = null;
                    //删除所有旧的成员
                    projectMemberMapper.delYFMembers(proId);
                }

                List<String> authorPids = new ArrayList<>();
                List<String> authorUnits = new ArrayList<>();
                for(int m = 0; m < memberYfList.size();m++){
                    BizYfContractMember bizYfContractMember = memberYfList.get(m);
                    bizYfContractMember.setOrderId((long)(m+1));
                    yfContractMemberMapper.insert(bizYfContractMember);

                    //反写主表
                    authorPids.add(bizYfContractMember.getPersonId());
                    authorUnits.add(bizYfContractMember.getUnitId());
                    BizYfContract bizYfContract = new BizYfContract();
                    bizYfContract.setAuthorpids(authorPids.stream().collect(Collectors.joining(",")));
                    bizYfContract.setAuthorunitids(authorUnits.stream().collect(Collectors.joining(",")));
                    bizYfContract.setId(proId);
                    yfContractMapper.updateById(bizYfContract);
                }
            }
        }catch (Exception exception){
            res = "保存项目成员信息失败！";
        }

        return res;
    }

    /**
     * 删除成员信息(根据项目号删除；根据id批量删除)
     * @param ids
     * @param proId 项目号
     * @param proType xj或zx
     * @return
     */
    public String delMemberInfo(String[] ids, String proId,String proType){
        String res= "删除成功！";
        int delRes = 0;
        try{
            if(StringUtils.isNotBlank(proId)){
                //根据项目号批量删除
                delRes = proType.equals("xj")?xjProjectMemberMapper.delMemberByProId(proId):zxProjectMemberMapper.delMemberByProId(proId);
            }else if(ids != null){
                delRes =proType.equals("xj")? xjProjectMemberMapper.deleteBatchIds(Arrays.asList(ids)):zxProjectMemberMapper.delMemberByProId(proId);
            }
        }catch (Exception exception){
            res = "删除成员信息失败！" + exception.getMessage();
        }

        return res;
    }

    /**
     * 根据项目成员获取项目id
     * @param memberName 成员姓名
     * @return
     */
    public String getProIdByMemberName(String memberName){
        String res = "";
        try{
            VProjectMemberBo memBo = new VProjectMemberBo();
            memBo.setPersonName(memberName);

            List<BizZxProjectMember> list = getMemList(memBo);
            if(list!=null && list.size()>0){
                for(int m = 0; m < list.size(); m++){
                    res = StringUtils.isNotBlank(res)?res+"','"+list.get(0).getProjectId():list.get(0).getProjectId();
                }
                return res;
            }else{
                return "";
            }
        }catch (Exception exception){
            return "";
        }
    }

    /**
     * 新建项目后保存负责人信息入成员表
     * @param proId
     * @param type
     * @return
     */
    public int saveFzrByProId(String proId, String type){
        int res = 0;
        SciencePersonBo personBo = new SciencePersonBo();
        try{
            if(StringUtils.isNotBlank(proId)){
                QueryWrapper<VProject> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("ID",proId);
                VProject proInfo = projectInitMapper.selectOne(queryWrapper);

                if(proInfo != null){
                    String chargerCode = proInfo.getChargerCode();
                    if(StringUtils.isNotBlank(chargerCode)){
                        //
                        SciencePersonVo sciencePersonVo = new SciencePersonVo();
                        sciencePersonVo.setId(chargerCode);
                        List<SciencePersonBo> sciencePersons = sciencePersonService.personDetails(sciencePersonVo);
                        if(sciencePersons != null && sciencePersons.size()>0){
                            personBo = sciencePersons.get(0);
                        }
                    }else{
                        //负责人是校外人员
                        personBo.setName(proInfo.getChargerName());
                    }

                    BizXjProjectMember xJMemberInfo = this.getmemberInfoFromBizPer(personBo,proId);
                    if(type.equals("xj")){
                        xJMemberInfo.setMemberType("1"); //校级的负责人的成员类型默认是教师
                        xjProjectMemberMapper.insert(xJMemberInfo);
                    }else{
                        xJMemberInfo.setMemberType(proInfo.getChargerType());
                        BizZxProjectMember zxMemberInfo = new BizZxProjectMember();
                        BeanUtils.copyProperties(xJMemberInfo,zxMemberInfo);
                        zxMemberInfo.setIdCard(personBo.getIdCard());
                        zxProjectMemberMapper.insert(zxMemberInfo);
                    }
                }
            }
        }catch (Exception exception){
            String ex = exception.getMessage();
        }

        return res;
    }

    /**
     * 根据用户信息构建成员的第一条负责人（校、纵）
     * @param personBo
     * @param proId
     * @return
     */
    public BizXjProjectMember getmemberInfoFromBizPer(SciencePersonBo personBo,String proId){
        BizXjProjectMember xJMemberInfo = new BizXjProjectMember();
        xJMemberInfo.setProjectId(proId);
        xJMemberInfo.setPersonName(personBo.getName());
        //根据负责人id获取负责人详情
        //先写在校级项目里，后面映射给纵向
        if(StringUtils.isNotBlank(personBo.getId())){
            xJMemberInfo.setPersonName(personBo.getName());
            xJMemberInfo.setPersonId(personBo.getId());
            xJMemberInfo.setPersonCode(personBo.getAccount());
            xJMemberInfo.setUnitId(personBo.getUnitId());
            xJMemberInfo.setUnitName(personBo.getUnitName());
            xJMemberInfo.setSubjectId(personBo.getSearchId());
            xJMemberInfo.setTitleId(personBo.getTitleId());
            xJMemberInfo.setEduLevelId(personBo.getEduLevelId());
            xJMemberInfo.setEduDegreeId(personBo.getEduDegreeId());
            xJMemberInfo.setSexId(personBo.getSexId());
        }

        xJMemberInfo.setOrderId(Long.parseLong("1"));
        xJMemberInfo.setBearTypeId("1");
        xJMemberInfo.setJoinStateId("1");
        xJMemberInfo.setWorkRatio(new BigDecimal(0));
        return xJMemberInfo;
    }

    public BizYfContractMember getmemberInfoFromBizPerYF(SciencePersonBo personBo,String proId){
        BizYfContractMember yfContractMember = new BizYfContractMember();
        yfContractMember.setContractId(proId);
        yfContractMember.setPersonName(personBo.getName());
        if(StringUtils.isNotBlank(personBo.getId())){
            yfContractMember.setPersonId(personBo.getId());
            yfContractMember.setPersonCode(personBo.getAccount());
            yfContractMember.setCode(personBo.getAccount());
            yfContractMember.setUnitId(personBo.getUnitId());
            yfContractMember.setUnitName(personBo.getUnitName());
            yfContractMember.setSubjectId(personBo.getSearchId());
            yfContractMember.setTitleId(personBo.getTitleId());
            yfContractMember.setEduLevelId(personBo.getEduLevelId());
            yfContractMember.setEduDegreeId(personBo.getEduDegreeId());
            yfContractMember.setSexId(personBo.getSexId());
        }
        //承担类型 默认1->负责人
        yfContractMember.setBearTypeId("1");
        return yfContractMember;
    }

    /**
     * 变更审核后处理项目成员表（只有校级、纵向有成员变更）+ 基础信息负责人变更
     * @param proId 项目号
     * @param proClass 项目类型
     * @param type 变更类型
     * @param memberAlterations 变更成员从表
     */
    public void changeMemberInfo(String proId, String proClass, String type, List<BizProjectMemberAlteration> memberAlterations){
        try{
            if(type.equals("member")){
                //成员变更后的业务:成员变更表中有所有的成员，取参与状态不为0的构建新的list（先构建zx，xj重新处理）
                List<BizZxProjectMember> zxProjectMemberList = this.getMemberListFromAlter(proId,memberAlterations);
                if(proClass.equals("xJProject")){
                    List<BizXjProjectMember> xjProjectMemberList = this.getXJMemberListFromZx(zxProjectMemberList);
                    this.saveXjMemberInfos(xjProjectMemberList);
                }else if(proClass.equals("zXProject")){
                    this.saveZxMemberInfos(zxProjectMemberList);
                }
            }else{
                //负责人变更后的业务：list只有新负责人的personId和chargerType
                //1、基础信息保存时负责人变更-》校级、纵向
                //2、项目变更审核通过后负责人变更-》横向（横向才有负责人变更）
                SciencePersonBo personBo = new SciencePersonBo();
                String newChagerCode = memberAlterations.get(0).getPersonId();
                SciencePersonVo sciencePersonVo = new SciencePersonVo();
                if(StringUtils.isNotBlank(newChagerCode)){
                    //变更后的负责人是校内的，有code
                    sciencePersonVo.setId(memberAlterations.get(0).getPersonId());//获取新的负责人信息
                    List<SciencePersonBo> sciencePersons = sciencePersonService.personDetails(sciencePersonVo);
                    if(sciencePersons != null && sciencePersons.size()>0){
                        personBo = sciencePersons.get(0);
                    }
                }else{
                    personBo.setName(memberAlterations.get(0).getPersonName());
                }

                if(!proClass.equals("yfContract")){
                    BizXjProjectMember xjProjectMember = this.getmemberInfoFromBizPer(personBo,proId);//将修改后的负责人转为成员表中的负责人
                    xjProjectMember.setMemberType(memberAlterations.get(0).getMemberType());
                    //获取原本的成员数据
                    VProjectMemberBo projectMemberBo = new VProjectMemberBo();
                    projectMemberBo.setProjectId(proId);
                    List<BizZxProjectMember> oldMemList = this.getMemList(projectMemberBo);

                    //旧成员数据里去掉和新负责人一样的成员信息（根据名字判断）
//                    oldMemList = oldMemList.stream()
//                            .filter(person -> !person.getPersonName().equals(xjProjectMember.getPersonName()))
//                            .collect(Collectors.toList());
                    oldMemList = this.cutSameMember(oldMemList,BizZxProjectMember::getPersonName, BizZxProjectMember::getPersonCode,
                            xjProjectMember.getMemberType(),xjProjectMember.getPersonName(),xjProjectMember.getPersonCode(),BizZxProjectMember::setBearTypeId);

                    if(proClass.equals("xJProject")){
                        //将获取到的旧人员数据转一下
                        List<BizXjProjectMember> converList = this.getXJMemberListFromZx(oldMemList);
                        //将负责人信息放到成员list的第一条后保存成员信息
                        converList.add(0,xjProjectMember);
                        this.saveXjMemberInfos(converList);
                    }else if(proClass.equals("zXProject")){
                        BizZxProjectMember zxProjectMember = new BizZxProjectMember();
                        BeanUtils.copyProperties(xjProjectMember,zxProjectMember); //获取到的校级映射给纵向
                        oldMemList.get(0).setBearTypeId("3");//第一条数据的负责人类型改为参与人
                        oldMemList.add(0,zxProjectMember);
                        this.saveZxMemberInfos(oldMemList);
                    }
                }else{
                    //获取到的新的负责人
                    BizYfContractMember yfContractMember = this.getmemberInfoFromBizPerYF(personBo,proId);//将修改后的负责人转为成员表中的负责人
                    yfContractMember.setMemberType(memberAlterations.get(0).getMemberType());
                    //获取原本的成员数据
                    LambdaQueryWrapper<BizYfContractMember> query=new LambdaQueryWrapper<>();
                    query.orderBy(true,true,BizYfContractMember::getOrderId);
                    query.eq(BizYfContractMember::getContractId,proId);
                    List<BizYfContractMember> oldMemList = yfContractMemberMapper.selectList(query);
                    //旧成员数据里去掉和新负责人一样的成员信息（根据名字判断）
                    oldMemList = this.cutSameMember(oldMemList,BizYfContractMember::getPersonName, BizYfContractMember::getPersonCode,
                            yfContractMember.getMemberType(),yfContractMember.getPersonName(),yfContractMember.getPersonCode(),BizYfContractMember::setBearTypeId);
                    //将负责人信息放到成员list的第一条后保存成员信息
                    oldMemList.add(0,yfContractMember);
                    this.saveYFMemberInfos(oldMemList);
                }
            }
        }catch (Exception exception){
            String ex = exception.getMessage();
        }
    }

    /**
     * 成员变更转纵向
     * @param proId
     * @param memberAlterations
     * @return
     */
    private List<BizZxProjectMember> getMemberListFromAlter(String proId,List<BizProjectMemberAlteration> memberAlterations){
        //成员变更转纵向
        if(memberAlterations != null && memberAlterations.size()>0){
            return memberAlterations.stream().map(a->{
                if(!a.getJoinStateId().equals("0")){
                    BizZxProjectMember b = new BizZxProjectMember();
                    b.setProjectId(proId);
                    b.setMemberType(a.getMemberType());
                    b.setPersonId(a.getPersonId());
                    b.setPersonCode(a.getPersonCode());
                    b.setPersonName(a.getPersonName());
                    b.setUnitId(a.getUnitId());
                    b.setUnitName(a.getUnitName());
                    b.setSubjectId(a.getSubjectId());
                    b.setTitleId(a.getTitleId());
                    b.setEduLevelId(a.getEduLevelId());
                    b.setEduDegreeId(a.getEduDegreeId());
                    b.setSexId(a.getSexId());
                    b.setBearTypeId(a.getBearTypeId());
                    b.setJoinStateId(a.getJoinStateId());
                    b.setWorkRatio(a.getWorkRatio());
                    return b;
                }else{
                    return null;
                }
            }).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 纵向转校级
     * @param oldMemberList
     * @return
     */
    private List<BizXjProjectMember> getXJMemberListFromZx(List<BizZxProjectMember> oldMemberList){
        //纵向转校级
        List<BizXjProjectMember> res= new ArrayList<>();
        try{
            if(oldMemberList != null && oldMemberList.size()>0){
                for(BizZxProjectMember a:oldMemberList){
                    if(a != null){
                        BizXjProjectMember b = new BizXjProjectMember();
                        b.setProjectId(a.getProjectId());
                        b.setMemberType(a.getMemberType());
                        b.setPersonId(a.getPersonId());
                        b.setPersonCode(a.getPersonCode());
                        b.setPersonName(a.getPersonName());
                        b.setUnitId(a.getUnitId());
                        b.setUnitName(a.getUnitName());
                        b.setSubjectId(a.getSubjectId());
                        b.setTitleId(a.getTitleId());
                        b.setEduLevelId(a.getEduLevelId());
                        b.setEduDegreeId(a.getEduDegreeId());
                        b.setSexId(a.getSexId());
                        b.setJoinStateId(a.getJoinStateId());
                        b.setWorkRatio(a.getWorkRatio());
                        b.setEduLevelId(a.getJoinStateId());
                        b.setBearTypeId(!StringUtils.isNotBlank(a.getBearTypeId()) ? !a.equals(oldMemberList.get(0)) ? "3":"1" : a.getBearTypeId()); // 承担类型处理
                        res.add(b);
                    }
                }
            }
        }catch (Exception exception){
            res = null;
        }
        return res;
    }

    /**
     * 去掉成员列表中和新负责人相同的数据
     * @param oldMemList
     * @param getPersonName
     * @param getPersonCode
     * @return
     * @param <T>
     */
    private <T> List<T> cutSameMember(List<T> oldMemList, Function<T,String> getPersonName, Function<T,String> getPersonCode,
                                      String newType, String newName, String newCode, BiConsumer<T,String> setBearTypeId){
        try{
            int oldLength = oldMemList.size();
            for(int i = 0; i < oldMemList.size(); i++){
                T person = oldMemList.get(i);
                String nameNow = getPersonName.apply(person);
                String codeNow = getPersonCode.apply(person);
                if(!newType.equals("3") && nameNow.equals(newName) && codeNow.equals(newCode)){
                    oldMemList.remove(i);
                    break;
                }
            }

//            if(!newType.equals("3") && oldLength == oldMemList.size()){
//                setBearTypeId.accept(oldMemList.get(0),"3");
//            }
            setBearTypeId.accept(oldMemList.get(0),"3");//直接变成负责人，这时候的第一个人必是旧负责人
        }catch(Exception exception){
            String ex = exception.getMessage();
        }
        return oldMemList;
    }
}
